package de.hochschuletrier.bachelor.antfarm.control;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Point;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.newdawn.slick.GameContainer;

import de.hochschuletrier.bachelor.antfarm.control.handler.ActionMessageSelectionHandler;
import de.hochschuletrier.bachelor.antfarm.entity.Ant;
import de.hochschuletrier.bachelor.antfarm.entity.Entity;
import de.hochschuletrier.bachelor.antfarm.entity.Foodsource;
import de.hochschuletrier.bachelor.antfarm.entity.Nest;
import de.hochschuletrier.bachelor.antfarm.entity.listener.IEntityListener;
import de.hochschuletrier.bachelor.antfarm.entity.listener.IEntityMessageListener;
import de.hochschuletrier.bachelor.antfarm.entity.mes.ActionMessageGroup;
import de.hochschuletrier.bachelor.antfarm.settings.Settings;
import de.hochschuletrier.bachelor.antfarm.world.World;

public class ControlFrame extends JFrame implements ChangeListener, ListSelectionListener, IEntityListener, IEntityMessageListener {
	private static final long serialVersionUID = -2418088990144268649L;

	private JTextArea textArea;
	private JList<Entity> entityList;
	private JList<ActionMessageGroup> messageList;
	private DefaultListModel<ActionMessageGroup> messageListModel;

	private Entity selectedEntity;
	private JPanel attributesPanel;

	public ControlFrame(GameContainer gc, World world) {
		this.setSize(600, 800);
		this.setLocation(gc.getScreenWidth() - this.getWidth(), 0);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLayout(new BorderLayout());

		// /////////////////////////////////////
		// North-Panel: Slider um Frames pro Sekunde einzustellen
		JPanel sliderPanel = new JPanel();
		this.add(sliderPanel, BorderLayout.NORTH);
		JLabel sliderLabel = new JLabel("Berechnete Frames pro Sekunde: ");
		sliderPanel.add(sliderLabel);
		JSlider speedSlider = new JSlider(0, 10, (int) Settings.getCalculatedFramesPerSecond());
		sliderPanel.add(speedSlider);
		speedSlider.addChangeListener(this);

		// /////////////////////////////////////
		// Center-Panel: Einheiten-Selektion
		JPanel center = new JPanel();
		this.add(center);
		center.setLayout(new GridLayout(0, 1));

		// Entities
		JPanel entitiesPanel = new JPanel();
		center.add(new JScrollPane(entitiesPanel));
		entitiesPanel.setLayout(new BorderLayout());

		entitiesPanel.add(new JLabel("Einheitenauswahl"), BorderLayout.NORTH);

		Entity[] list = new Entity[world.getEntities().size()];
		
		int i = 0;
		for (Entity e : world.getEntities()) {
			list[i++] = e;
		}	
		entityList = new JList<Entity>(list);
		entitiesPanel.add(entityList);
		entityList.addListSelectionListener(this);
		entityList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		// Messages
		JPanel mesPanel = new JPanel();
		center.add(new JScrollPane(mesPanel));
		mesPanel.setLayout(new BorderLayout());

		mesPanel.add(new JLabel("Vorhandene Nachrichten"), BorderLayout.NORTH);

		messageListModel = new DefaultListModel<ActionMessageGroup>();
		messageList = new JList<ActionMessageGroup>(messageListModel);
		mesPanel.add(messageList);
		messageList.addListSelectionListener(new ActionMessageSelectionHandler(this));
		messageList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		// TextFenster
		JPanel textPanel = new JPanel();
		center.add(new JScrollPane(textPanel));
		textPanel.setLayout(new BorderLayout());
		textArea = new JTextArea();
		textPanel.add(textArea);
		textArea.setEditable(false);

		// /////////////////////////////////////
		// East-Panel: Eigenschaften
		attributesPanel = new JPanel();
		this.add(attributesPanel, BorderLayout.EAST);
		attributesPanel.setLayout(new BoxLayout(attributesPanel, BoxLayout.Y_AXIS));
		int borderSize = 5;
		attributesPanel.setBorder(BorderFactory.createEmptyBorder(borderSize, borderSize, borderSize, borderSize));
		setAttributesPanel();

		this.setVisible(true);
	}

	private void setAttributesPanel() {
		attributesPanel.removeAll();

		String s = "";
		if (selectedEntity != null) {
			s = selectedEntity.getName();
		}
		attributesPanel.add(new JLabel("Name: " + s));

		if (selectedEntity != null) {
			s = "" + selectedEntity.getId();
		}
		attributesPanel.add(new JLabel("ID: " + s));

		if (selectedEntity != null) {
			s = "" + selectedEntity.getX();
		}
		attributesPanel.add(new JLabel("X: " + s));

		if (selectedEntity != null) {
			s = "" + selectedEntity.getY();
		}
		attributesPanel.add(new JLabel("Y: " + s));

		if (selectedEntity != null) {
			s = "" + selectedEntity.getMessages().size();
		}
		attributesPanel.add(new JLabel("Nachrichten: " + s));

		attributesPanel.add(new JLabel(" "));

		/**
		 * Ants
		 */
		if (selectedEntity != null && selectedEntity instanceof Ant) {
			Ant ant = (Ant) selectedEntity;

			attributesPanel.add(new JLabel("State: " + ant.getState().getName()));

			if (ant.getFoodpiece() != null) {
				attributesPanel.add(new JLabel("Item: " + ant.getFoodpiece().getEnergy()));
			}
			else {

				attributesPanel.add(new JLabel("Item: keins"));
			}

			int i = 1;
			for (Point p : ant.getLastPositions()) {
				attributesPanel.add(new JLabel("Letzter Punkt (" + i + "): " + p.x + "|" + p.y));
				i++;
			}
		}
		/**
		 * Nest
		 */
		else if (selectedEntity != null && selectedEntity instanceof Nest) {
			Nest nest = (Nest) selectedEntity;

			attributesPanel.add(new JLabel("Sucher: " + nest.getScoutingAnts()));
			attributesPanel.add(new JLabel("Sammler: " + nest.getCollectingAnts()));

			attributesPanel.add(new JLabel("Vorrat: " + nest.getEnergy()));

			int knownFoodpieces = 0;
			for (Foodsource src : nest.getKnownFoodsources()) {
				knownFoodpieces += src.getAmountOfFoodpieces();
			}
			attributesPanel.add(new JLabel("Kenne Foodpieces: " + knownFoodpieces));
		}

		attributesPanel.updateUI();
	}

	@Override
	public void stateChanged(ChangeEvent e) {
		JSlider src = (JSlider) e.getSource();
		int value = src.getValue();
		Settings.setCalculatedFramesPerSecond(value);
	}

	@Override
	public void valueChanged(ListSelectionEvent e) {
		if (selectedEntity != null) {
			selectedEntity.removeEntityListener(this);
			selectedEntity.removeMessageListener(this);
		}

		@SuppressWarnings("unchecked")
		JList<Entity> list = (JList<Entity>) e.getSource();
		Entity selectedEntity = list.getSelectedValue();
		World.getInstance().setSelectedEntity(selectedEntity);
		this.selectedEntity = selectedEntity;
		setAttributesPanel();

		if (selectedEntity != null) {
			selectedEntity.addEntityListener(this);
			selectedEntity.addMessageListener(this);
		}

		messageListModel.removeAllElements();
		for (ActionMessageGroup g : selectedEntity.getMessages()) {
			messageListModel.addElement(g);
		}
	}

	public JTextArea getTextArea() {
		return textArea;
	}

	@Override
	public void entityChanged(Entity e) {
		setAttributesPanel();
	}

	@Override
	public void entityMessageAdded(ActionMessageGroup g) {
		messageListModel.addElement(g);
		messageList.updateUI();
	}
}